class PoolUtil
{
    private static _poolDict:any={};
    private static _poolCfgDict:any={};
    private static _poolClasses:string[];
    private static _classInfos:any[]=[];
    public static registerClassInfo(cls:any,className:string,types:string[]=null)
    {
        if(cls.__class__)return;
        cls.__class__ = className;
        cls.__types__ = types;
    }
    private static getClassName(cls:any):string    
    {
        if(cls.__class__ == null)
        {
            console.error("类型未注册!" + cls);
            return null;
        }
        return cls.__class__;
    }
    /**设置对象池数量溢出警告的溢出临界值*/
    public static setPoolLengthWarn(cls:any,maxNum:number):void
    {   
        let className:string = PoolUtil.getClassName(cls);
        if(PoolUtil._poolCfgDict[className] == null)PoolUtil._poolCfgDict[className]={};
        PoolUtil._poolCfgDict[className].max = maxNum;
    }
    /**获取对象池数量溢出警告的溢出临界值*/
    public static getPoolLengthWarn(cls:any):number
    {        
        let className = PoolUtil.getClassName(cls);
        if(PoolUtil._poolCfgDict[className] == null)PoolUtil._poolCfgDict[className]={};
        return PoolUtil._poolCfgDict[className].max?PoolUtil._poolCfgDict[className].max:100;
    }
    /**从对象池取出*/
    public static fromPool(cls:any):IPoolObject
    {
        let className:string = PoolUtil.getClassName(cls);
        if(PoolUtil._poolDict[className] == null)PoolUtil._poolDict[className]=new Array<IPoolObject>();
        var pool:IPoolObject[];
        pool = PoolUtil._poolDict[className];			
        var r:IPoolObject;
        r = pool.length==0?new cls():pool.pop();
        r.inPool = false;
        r.outPoolInit();
        return r;
    }
    /**回收入对象池*/
    public static toPool(poolObject:IPoolObject,cls:any):void
    {
       let className:string = PoolUtil.getClassName(cls);
        var pool:IPoolObject[],poolCfg:any;
        var max:number;
        pool = PoolUtil._poolDict[className];
        if(pool)
        {
            poolObject.inPool = true;
            poolCfg = PoolUtil._poolCfgDict[className];
            max = poolCfg && poolCfg.max?poolCfg.max:100;
            if(pool.length > max)
                console.warn("pool over " + max + "!#" + className + ",length:" + pool.length);
            pool.push(poolObject);
        }			
    }
    /**销毁池子*/
    public static destroyPool(cls:any, includeExtend:boolean=false):void
    {
        let i:number,len:number,len2:number;
        let arr:IPoolObject[];
        
        if(cls == null)return;
        let className:string = PoolUtil.getClassName(cls);
        let delArr:string[] = [];
        let objArr:string[];
        if(includeExtend)
        {
            let clsArr:any[];				
            for(var key in PoolUtil._poolDict)
            {
                let obj:any=window;
                objArr = key.split(".");
                len = objArr.length;
                for(i=0;i<len;++i)
                {						
                    obj = obj[objArr[i]];
                    if(obj == null)													
                        break;													
                }
                if(obj == null)continue;
                clsArr = obj.prototype.__types__;
                if(clsArr == null)continue;
                if(clsArr.indexOf(className) > -1)
                {
                    delArr.push(key);
                }
            }
            if(delArr.length == 0)
                return;
        }
        else
        {				
            arr = PoolUtil._poolDict[className];
            if(arr == null)return;
            delArr.push(className);
        }
        
        len2 = delArr.length;
        while(--len2 > -1)
        {
            arr = PoolUtil._poolDict[delArr[len2]];
            len = arr.length;
            while(--len>-1)
            {
                if(arr[len].dispose!=null)
                    arr[len].dispose();
            }
            arr.length = 0;
            delete PoolUtil._poolCfgDict[delArr[len2]];
            delete PoolUtil._poolDict[delArr[len2]];
        }			
    }
    public static dispose():void
    {
        PoolUtil._poolCfgDict = {};
        PoolUtil._poolDict = {};
        PoolUtil._classInfos = [];
    }
}